package org.dromara.common.excel.convert;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.excel.converters.Converter;
import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.GlobalConfiguration;
import com.alibaba.excel.metadata.data.ReadCellData;
import com.alibaba.excel.metadata.data.WriteCellData;
import com.alibaba.excel.metadata.property.ExcelContentProperty;
import lombok.extern.slf4j.Slf4j;

import java.math.BigDecimal;


/**
 * @Author 刘武贵
 * @Date 2024/8/15 22:00
 * @Description 功能描述：大数值转换
 * Excel 数值长度位15位 大于15位的数值转换位字符串
 */
@Slf4j
/**
 * 实现了Long类型与Excel单元格数据类型的相互转换
 * 主要用于处理大数字在Excel中的读写问题，确保数字的准确性
 */
public class ExcelBigNumberConvert implements Converter<Long> {

    /**
     * 获取支持的Java类型
     *
     * @return Long类型，表示此转换器支持将Excel单元格数据转换为Long类型
     */
    @Override
    public Class<Long> supportJavaTypeKey() {
        return Long.class;
    }

    /**
     * 获取支持的Excel类型
     *
     * @return STRING类型，表示此转换器在Excel中将数据存储为字符串
     */
    @Override
    public CellDataTypeEnum supportExcelTypeKey() {
        return CellDataTypeEnum.STRING;
    }

    /**
     * 将Excel单元格数据转换为Java中的Long类型
     *
     * @param cellData 单元格数据，可能包含任何类型的数据
     * @param contentProperty Excel内容属性，可能包含格式等信息
     * @param globalConfiguration 全局配置信息
     * @return 转换后的Long类型数据
     */
    @Override
    public Long convertToJavaData(ReadCellData<?> cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) {
        return Convert.toLong(cellData.getData());
    }

    /**
     * 将Java中的Long类型数据转换为Excel单元格数据
     *
     * @param object 需要转换的Long类型数据
     * @param contentProperty Excel内容属性，可能包含格式等信息
     * @param globalConfiguration 全局配置信息
     * @return 转换后的Excel单元格数据对象
     */
    @Override
    public WriteCellData<Object> convertToExcelData(Long object, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) {
        // 检查是否数据为空或者长度超过15位，超过则转为字符串存储，以避免精度丢失
        if (ObjectUtil.isNotNull(object)) {
            String str = Convert.toStr(object);
            if (str.length() > 15) {
                return new WriteCellData<>(str);
            }
        }
        // 将数据存储为数字类型，使用BigDecimal保持数据精度
        WriteCellData<Object> cellData = new WriteCellData<>(new BigDecimal(object));
        cellData.setType(CellDataTypeEnum.NUMBER);
        return cellData;
    }


}
